<style scoped>
.address-tree-container {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
}



.selected-address {
  padding: 8px 12px;
  background-color: #f5f7fa;
  border-top: 1px solid #dcdfe6;
  font-size: 12px;
  color: #606266;
}

.aa{
  margin-left: 10px;
  margin-top: 10px;
}
#tb{
  margin-bottom: 10px;
  margin-top: 10px;
}
.la{
  width: 350px;
}
.avatar{
  width: 200px;
  height: 200px;
  border:1px solid red;
  text-align: center;
}
.avatar-uploader-icon{
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
.row-avatar{
  width: 60px;
  height: 60px;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center center;
}
</style>

<template>
<!--  查询区-->
  <div class="search" >
    <el-form inline :model="memberSearchModel"  ref="msm" >
      <el-form-item label="ID:" style="width: 200px" prop="id">
        <el-input v-model="memberSearchModel.id" placeholder="请输入id"></el-input>

      </el-form-item>

      <el-form-item label="姓名:" style="width: 200px" prop="name" >
        <el-input v-model="memberSearchModel.name" placeholder="请输入姓名" ></el-input>
      </el-form-item>

      <el-form-item label="性别:" prop="sex">
        <el-select v-model="memberSearchModel.sex" style="width: 120px" :empty-values="[null]">
          <el-option label="全部" value=""></el-option>
          <el-option label="男" value="男"></el-option>
          <el-option label="女" value="女"></el-option>
        </el-select>
      </el-form-item>


      <el-form-item label="出生日期:" prop="birthdayRange">
        <el-date-picker
          type="daterange"
          range-separator="~"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          v-model="memberSearchModel.birthdayRange"
          value-format="YYYY-MM-DD"
        />

      </el-form-item>

      <el-form-item label="手机号:" prop="phone">
        <el-input v-model="memberSearchModel.phone" placeholder="请输入手机号"></el-input>
      </el-form-item>
    </el-form>
  </div>

<!--  按钮区-->
  <div class="action">
    <el-button type="primary" :icon="Search" @click="search()">查询</el-button>
    <el-button type="primary" :icon="CirclePlus" @click="add">添加</el-button>
    <el-button type="primary" :icon="Edit" @click="edit">修改</el-button>
    <el-button type="primary" :icon="Refresh" @click="reset">重置</el-button>
    <el-button type="danger"  :icon="Delete"  @click="remove" >批量删除</el-button>
  </div>

<!--  表格-->
  <div class="grid" id="tb" >
    <el-table :data="members" stripe border @rowClick="tbRowClick" ref="tblRef">
      <el-table-column type="selection"  width="50" align="center" />
      <el-table-column  prop="id" label="ID" width="80" fixed="left"/>
      <el-table-column label="头像" fixed>
        <template #default="scope">
          <div class="row-avatar" :style="'background-image: url('+(scope.row.portrait )+ ')' "></div>
        </template>
      </el-table-column>
      <el-table-column  prop="account"  label="账号" width="140" fixed="left"/>
      <el-table-column  prop="password"  label="密码" width="100" fixed="left">
        <span>******</span>
      </el-table-column>
      <el-table-column  prop="name"  label="姓名" width="100" fixed="left"/>
      <el-table-column  prop="sex" label="性别" width="70"  >
        <template #default="scope">
          <el-tag v-if="scope.row.sex==='男'" type="primary" effect="dark">{{scope.row.sex}}</el-tag>
          <el-tag v-else type="danger" effect="dark">{{scope.row.sex}}</el-tag>
        </template>
      </el-table-column>
      <el-table-column  prop="birthday" label="出生日期" width="150" />
      <el-table-column  prop="phone" label="手机" width="180"/>
      <!-- 修改地址列显示 -->
      <el-table-column prop="addressId" label="地址" width="250">
        <template #default="scope">
          <span>{{ scope.row.address.name||scope.row.addressId }}</span>
        </template>
      </el-table-column>

      <el-table-column label="操作" width="200px" align="center" fixed="right">
        <template #default="scope">

          <el-button type="primary" size="small" @click="handleEdit(scope.row.id)">修改</el-button>
          <el-button type="danger" size="small" @click="remove(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>


<!--分页区-->
  <div class="pagination" >
    <el-pagination
        v-model:current-page="memberPi.pageNo"
        v-model:page-size="memberPi.pageSize"
        :page-sizes="[10, 20, 30, 40, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="memberPi.total"
        class="aa"
        @change="memberPiChange"

    />
  </div>

<!--  添加/修改区-->

  <el-dialog v-model="memberDlgShow" :title="memberDlgTitle" width="600"
             :close-on-click-modal="false" draggable align-center  @close="resetMemberForm">
    <el-form label-width="100px" label-position="right"  :model="memberModel" ref="memberFormRef" :rules="rules">

      <el-row>
        <el-col :span="14" class="la">
          <el-form-item label="姓名：" prop="name" >
            <el-input v-model="memberModel.name" placeholder="请输入姓名"></el-input>
          </el-form-item>
          <el-form-item label="性别：" prop="sex">
            <el-radio-group v-model="memberModel.sex">
              <el-radio label="男" value="男" />
              <el-radio label="女" value="女"/>
            </el-radio-group>
          </el-form-item>

          <el-form-item label="出生日期：" prop="birthday">
            <el-date-picker
                type="date"
                placeholder="选择日期"
                value-format="YYYY-MM-DD"
                v-model="memberModel.birthday"
            />
          </el-form-item>
        </el-col>
        <el-col :span="10">
          <el-upload
              class="avatar"
              :http-request="handleAvatarUpload"
              :show-file-list="false"
              :headers="headers">
            <img v-if="memberModel.portrait" :src="memberModel.portrait" alt="会员头像" width="150px"/>
            <el-icon v-else class="avatar-uploader-icon">
              <Plus/>
            </el-icon>
          </el-upload>
        </el-col>
      </el-row>

      <el-form-item label="手机号：" prop="phone">
        <el-input placeholder="请输入手机号" v-model="memberModel.phone"></el-input>
      </el-form-item>

      <el-form-item label="用户名：" prop="account">
        <el-input placeholder="请输入用户名" v-model="memberModel.account"></el-input>
      </el-form-item>
      <el-form-item label="密码：" prop="password">
        <el-input placeholder="请输入密码" v-model="memberModel.password"></el-input>
      </el-form-item>

      <el-form-item label="地址：" prop="addressId">
        <div class="address-tree-container">
          <el-input
              v-model="addressQuery"
              placeholder="请输入地址关键字搜索"
              clearable
              @input="onAddressQueryChanged"
          />
          <el-tree-v2
              ref="addressTreeRef"
              :data="addressTree"
              :props="treeProps"
              :height="200"
              :filter-method="addressFilterMethod"
              highlight-current
              expand-on-click-node
              @node-click="handleAddressNodeClick"
          >
            <template #default="{ node }">
              <span>{{ node.label }}</span>
            </template>
          </el-tree-v2>
          <div v-if="selectedAddressName" class="selected-address">
            已选择: {{ selectedAddressName }}
          </div>
        </div>
      </el-form-item>



    </el-form>

    <template #footer>
     <div>
       <el-button type="primary" @click="doSubmit">确定</el-button>
        <el-button type="primary" @click="memberDlgShow=false">取消</el-button>
       </div>
    </template>
  </el-dialog>

<!--  修改-->

</template>


<script setup>
import {nextTick, onMounted, reactive, ref, toRaw} from "vue"
import {CirclePlus, Delete, Edit, Plus, Refresh, Search} from "@element-plus/icons-vue";
import {ElMessage, ElMessageBox} from "element-plus";
import {cloneDeep} from 'lodash';
import {getJwt} from "@/api/jwt.js";
import {createBrand, deleteBrand, getBrands, updateBrand, uploadPortrait} from "@/api/member.js";
import {getAddressTree} from "@/api/address.js";
//地址树
const addressTree = ref([])
const addressTreeRef = ref()
const selectedAddress = ref()
const selectedAddressName = ref('')
const addressQuery = ref('')
// 树形组件属性配置
const treeProps = {
  value: 'id',
  label: 'name',
  children: 'children'
}

// 获取地址树形结构
async function loadAddressTree() {
  try {
    const resp = await getAddressTree()
    console.log(resp)
    if (resp.success) {
      addressTree.value = resp.data
    }
  } catch (error) {
    ElMessage.error("获取地址数据失败")
    console.error(error)
  }
}

//处理地址点击
function handleAddressNodeClick(data) {
   selectedAddress.value = data.id
   selectedAddressName.value = data.name
  memberModel.value.addressId=data.id
  addressQuery.value = data.name
}

//地址查询变化
function onAddressQueryChanged(query){
  if(addressTreeRef.value){
    addressTreeRef.value.filter(query)
  }
}

// 地址树过滤方法
const addressFilterMethod = (query, node) => {
  return node.label.includes(query)
}



let members = ref();
const headers = { Authorization: getJwt() };

let memberPi = reactive({
  pageNo: 1,
  pageSize: 10,
  total: 0
});

let msm = ref();

function reset() {
  msm.value?.resetFields();
  search(1, 10);
}

let tblRef = ref();

function tbRowClick(row) {
  tblRef.value?.toggleRowSelection(row);
}

async function remove() {
  let rows = tblRef.value.getSelectionRows();
  if (rows.length === 0) {
    ElMessage.warning("请选择要删除的行");
    return;
  }

  try {
    await ElMessageBox.confirm("确定要删除吗？", "警告", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    });

    let ids = rows.map(it => it.id);
    await removeByIds(ids);
  } catch (error) {
    // 用户取消操作
  }
}

async function removeByIds(ids) {
  try {
    let resp = await deleteBrand(ids);
    if (resp.success) {
      ElMessage.success(`删除成功,共删除${ids.length}条`);
      await search(1, 10);
    } else {
      ElMessage.error("删除失败");
    }
  } catch (error) {
    ElMessage.error("删除失败");
  }
}

let memberSearchModel = ref({
  id: null,
  name: null,
  sex: null,
  birthdayRange: [],
  phone: ""
});
async function search(pageNo = memberPi.pageNo, pageSize = memberPi.pageSize) {
  const searchModel = memberSearchModel.value;
  // 深拷贝避免修改原模型（防止 birthdayRange 被删除后丢失）
  let params = cloneDeep(searchModel);




  if (params.birthdayRange && params.birthdayRange.length === 2) {
    params.birthdayFrom = params.birthdayRange[0];
    params.birthdayTo = params.birthdayRange[1];
  }
  delete params.birthdayRange;

  // 清理空值参数
  Object.keys(params).forEach(key => {
    if (params[key] === null || params[key] === '' || (Array.isArray(params[key]) && params[key].length === 0)) {
      delete params[key];
    }
  });

  // 添加分页参数到查询参数中
  params.pageNo = pageNo;
  params.pageSize = pageSize;


  try {
    let resp = await getBrands(params); // 直接传递 params，而不是解构

    memberPi.total = resp.data.total;
    memberPi.pageNo = resp.data.current;
    memberPi.pageSize = resp.data.size;
    members.value = resp.data.records;
  } catch (error) {
    ElMessage.error("查询失败");
    console.error(error);
  }
}

function memberPiChange(pageNo, pageSize) {
  search(pageNo, pageSize);
}

onMounted(async () => {
  await search(memberPi.pageNo, memberPi.pageSize);
});

let memberDlgTitle = ref("添加会员");
let mode = "add";
let memberDlgShow = ref(false);

function add() {
  memberDlgTitle.value = "添加会员";
  memberDlgShow.value = true;
  mode = "add";
  // 清空地址选择器
  nextTick(() => {
    selectedAddress.value = null
    selectedAddressName.value = ''
    addressQuery.value = ''
  })
}
// 在组件挂载时加载地址树
onMounted(async () => {
  await search(memberPi.pageNo, memberPi.pageSize);
  // 加载地址树形数据
  await loadAddressTree();
});
function handleEdit(id) {
  if (!id) {
    ElMessage.error("无效的ID");
    return;
  }

  // 从当前表格数据中查找对应的行
  const targetRow = members.value.find(item => item.id === id);

  if (!targetRow) {
    ElMessage.warning("未找到对应的会员信息");
    return;
  }

  // 调用现有的edit函数处理编辑逻辑
  edit(targetRow);
}
// 修改 edit 函数，使其可以接受行数据参数
function edit(row) {
  // 如果没有传入 row 参数，则使用选中的行（保持向后兼容）
  if (!row) {
    let rows = tblRef.value.getSelectionRows();

    if (rows.length === 0) {
      ElMessage.warning("请选择要修改的行");
      return;
    } else if (rows.length > 1) {
      ElMessage.warning("只能选择一行");
      return;
    }
    row = rows[0];
  }

  // 直接打开编辑对话框并填充数据
  memberDlgShow.value = true;
  memberDlgTitle.value = "修改会员";
  mode = "edit";

  nextTick(() => {
    memberModel.value = cloneDeep(toRaw(row));
    memberModel.value.password = '';

    // 地址回显逻辑
    if (memberModel.value.addressId && memberModel.value.address) {
      selectedAddress.value = memberModel.value.addressId
      selectedAddressName.value = memberModel.value.address.name
      addressQuery.value = memberModel.value.address.name
    } else {
      selectedAddress.value = null
      selectedAddressName.value = ''
      addressQuery.value = ''
    }
  });
}


async function submitEdit() {
  try {
    memberModel.value.password=null;
    let params = toRaw(memberModel.value);


    // 如果有待上传的头像文件，先上传头像
    if (pendingAvatarFile.value) {
      const avatarUrl = await uploadAvatarAndGetUrl(pendingAvatarFile.value);
      if (avatarUrl) {
        params.portrait = avatarUrl;
      } else {
        ElMessage.error("头像上传失败");
        return;
      }
    }
    let resp = await updateBrand(params.id, params);

    if (resp.success) {
      ElMessage.success("修改成功");
      memberDlgShow.value = false;
      resetPendingAvatar(); // 重置待上传文件（清除本地预览）
      await search();
    } else {
      ElMessage.error(resp.msg || "修改失败");
    }
  } catch (error) {
    ElMessage.error("修改失败");
  }
}

let memberModel = ref({
  id: null,
  name: null,
  sex: '男',
  birthday: null,
  phone: "",
  account: null,
  password: null,
  addressId: null,
  portrait: null,
  address:null
});

function doSubmit() {
  if (mode === "add") {
    submitAdd();
  } else if (mode === "edit") {
    submitEdit();
  }
}

function submitAdd() {
  memberFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        let params = toRaw(memberModel.value);
        if (pendingAvatarFile.value) {
          const avatarUrl = await uploadAvatarAndGetUrl(pendingAvatarFile.value);
          if (avatarUrl) {
            params.portrait = avatarUrl;
          } else {
            ElMessage.error("头像上传失败");
            return;
          }
        }
        let resp = await createBrand(params);

        if (resp.success) {
          ElMessage.success("添加成功");
          memberDlgShow.value = false;
          resetPendingAvatar(); // 重置待上传文件（清除本地预览）
          await search();
        } else {
          ElMessage.error(resp.msg || "添加失败");
        }
      } catch (error) {
        ElMessage.error("添加失败");
      }
    } else {
      ElMessage.error("请填写正确的数据");
    }
  });
}

let memberFormRef = ref();


const rules = {
  phone: [
    { required: true, message: "手机号不能为空", trigger: "blur" },
    { min: 11, max: 11, message: "手机号长度为11位", trigger: "blur" },
    { validator: validatePhone, trigger: "blur" }
  ],
  name: [
    { required: true, message: "会员名称不能为空", trigger: "blur" }
  ],
};
function validatePhone(value, callback) {
  // 类型检查
  if (typeof callback !== 'function') {
    console.error('Callback is not a function');
    return;
  }

  // 类型检查
  if (typeof value !== 'string') {
    return callback(new Error("请输入有效的手机号"));
  }

  // 空值检查
  if (!value.trim()) {
    return callback(new Error("手机号不能为空"));
  }

  // 格式检查
  if (value.startsWith("1") && value.length === 11) {
    return callback();
  } else {
    return callback(new Error("手机号必须以1开头且长度为11位"));
  }
}

// 添加一个新的变量来存储待上传的头像文件
let pendingAvatarFile = ref(null);

async function handleAvatarUpload(options) {
  const { file } = options;
  // 保存待上传文件
  pendingAvatarFile.value = file;

  // 创建本地预览URL
  const reader = new FileReader();
  reader.onload = (e) => {
    memberModel.value.portrait = e.target.result;
  };
  reader.readAsDataURL(file);

  ElMessage.info("头像已选择，将在保存时上传");


}
//上传头像并获取URL
async function uploadAvatarAndGetUrl(file) {
  try {
    const formData = new FormData();
    formData.append('file', file);

    // 如果是编辑模式且有用户ID，则添加ID参数
    if (mode === "edit" && memberModel.value.id) {
      formData.append('id', memberModel.value.id);
    }

    const resp = await uploadPortrait(formData);
    if (resp.success) {
      // 只返回URL，不直接修改memberModel
      return resp.data; // 返回头像URL
    } else {
      ElMessage.error(resp.msg || "头像上传失败");
      return null;
    }
  } catch (error) {
    ElMessage.error("头像上传失败: " + error.message);
    return null;
  }
}
// 清除本地预览
function resetPendingAvatar() {
  pendingAvatarFile.value = null;
  // 只清除本地预览URL（以data:开头的）
  if (memberModel.value.portrait && memberModel.value.portrait.startsWith('data:')) {
    memberModel.value.portrait = null;
  }
}


// 重置表单方法
function resetMemberForm() {
  memberFormRef.value?.resetFields();
  resetPendingAvatar();
  selectedAddress.value = null
  selectedAddressName.value = ''
  addressQuery.value = ''
}
</script>


